web

Color extensions

part of wslib

Methods for Color processing, conversion and naming.

Used by SVG

Color name libraries

*web ( name, alpha )

the web method creates a table with 151 standard web color names, as found at

http://www.w3schools.com/html/html_colornames.asp

This method can be used in various ways:

Color.web; // returns the table (an Event)

Color.web( \maroon ); // returns a color named "maroon"

Color.web[ \maroon ]; // also returns a color named "maroon"

Color.web.maroon; // and again returns a color named "maroon"

Color.web.keys.asArray.sort.dopostln; // post all names

*web16 ( name, alpha )

the web method creates a table with the 16 most common web color names, supported by the W3C HTML 4.0 standard. Works the same way as *web.

Color.web16.keys.asArray.sort.dopostln; // post all names

*xwindows ( name, alpha, includeGrayShades )

the web method creates a table with the X-windows colors as found in the Color code file in the ClassLibrary. Works the same way as *web. It is advisable to get the table into a variable once when using more then once for saving speed. The full table when includeGrayShades is true (default : false ) has 650 entries.

Color.xwindows( includeGrayShades: true ).keys.asArray.sort.dopostln; // post all names

(

var table, window, button, text, key;

table = Color.xwindows;

window = GUI.window.new( "colors" ).front;

text = GUI.staticText.new( window, Rect( 120, 10, 150, 20 ) );

button = GUI.button.new( window, Rect( 10, 10, 100, 20 ) )

.states_( [[ "new color" ]] )

.action_( {

key = table.keys.choose;

window.view.background = table[ key ];

text.string = key.asString;

} );

button.doAction;

)

Creation methods

*newHex ( hexName, alpha )

Creates a color from a web standard hex String or Symbol ( like "#FFAA00" ). The hexName can also be a decimal number, for example produced using 16xFFAA00.

Color.newHex( "FFAA00" );

Color.newHex( "#FFAA00" );

Color.newHex( 16xFFAA00 );

*newName ( name, table, includeXWindows )

Creates a color from a web name. If the name is a number or a hex String / Symbol, it works as *newHex. If the name is a color name which is in the *web color table, the associated color will be returned. You can also provide your own color table with the table argument. By default the web table is used, but if includeXWindows is true (default : false ) the web and xwindows tables are combined, including the grayshades. There is also name conversion going on, providing compatibility with various naming conventions:

Color.newName( "EEE8AA" );

Color.newName( "PaleGoldenrod" );

Color.newName( "pale_goldenrod" );

Color.newName( 16xEEE8AA );

Color.newName( "none" ); // same as Color.clear

Accessing and conversion methods

*web related

hex

convert the color to a hex string

Color.newName( "EEE8AA" ).hex; // proof of concept

webHex

convert the color to a hex string with a "#" char at the start

hexValue

convert the color to a decimal value derrived from the hex string

Color.newName( "EEE8AA" ).hexValue;

asWebColorString

convert the color to webcolor name if found or else a webHex string

Color.newName( "EEE8AA" ).asWebColorString; // pale_golenrod

Color.newName( "FFAA00" ).asWebColorString; // #FFAA00

asWebColorString can also be called on other objects:

Nil:asWebColorString ( default ) : returns default

String:asWebColorString ( default ) : returns default if not compatible

Symbol:asWebColorString ( default )

Number:asWebColorString ( default )

asColor

returns itself when called upon a Color, but returns a color when called upon a:

Number, String, Symbol or nil

asColor uses Color.newName internally

roundHex

returns a color rounded to the 24bit web color standard

Color(0.12345, 0.23456, 0.34567 ).asArray * 255;

Color(0.12345, 0.23456, 0.34567 ).roundHex.asArray * 255;

findWebColor ( table )

returns an alphabetically sorted array of web color names found with this color

Color.newName( "FF00FF" ).findWebColor; // returns 2 web color names with identical hex values

findSameHueNames ( table )

returns an alphabetically sorted array of web color names with the same hue as this color

(

var window, table;

table = Color.web; // make table once for optimized speed

window = GUI.window.new( "purple shades" ).front;

window.view.decorator = FlowLayout( window.view.bounds );

Color.newName( "purple", table ).findSameHueNames( table )

.sort({ |a,b| Color.newName( a, table).lightness <= Color.newName( b, table ).lightness })

.do({ |name|

GUI.compositeView.new( window, 50@380 )

.background_( Color.newName( name, table ) );

});

)

processing methods

hue, sat, val

gets and sets HSV values for colors as if they were instance variables

lightness

returns the mean of red, green and blue

desaturate

desaturates the color in place

clip ( min, max )

clips the red, green and blue values in place

round ( quant )

rounds the red, green and blue values in place

saturate ( amount )

returns a saturated or desaturated version of the color ( amount : -1 to 1 )

hueAdd ( amount )

returns a hue-shifted version of the color ( amount : -1 to 1 )

blendVal ( amount, toVal )

returns a val-changed version of the color ( amount : -1 to 1, toVal : 0 to 1, default 0.5 )

This changes the lightness to an average value, thus decreases/increases lightness differences between colors. Similar to contrast, but inversed and keeps color (doesn't fade to gray)

contrast ( amount )

returns a contrast changed version of the color ( amount : -1 to 1 )

brightness ( amount )

returns a brightness changed version of the color ( amount : -1 to 1 )

(

var window, button, comps, comps2, process, sliders;

window = GUI.window.new( "color processing", Rect(300, 100, 400, 282) ).front;

window.view.background_( Color.black );

window.view.decorator = FlowLayout( window.view.bounds );

comps = { GUI.compositeView.new( window, 40@25 ) } ! 9;

comps2 = { GUI.compositeView.new( window, 40@100 ) } ! 9;

process = { comps2.do({ |comp, i|

var newColor;

newColor = comps[i].background ?? { Color.clear };

sliders.do({ |sl, ii|

newColor = newColor.perform( sl[0], sl[1].value.linlin(0,1,-1,1) );

});

comp.background = newColor;

});

};

sliders = [ \saturate, \hueAdd, \blendVal, \contrast, \brightness ].collect({ |item, i|

[ item,

GUI.slider.new( window, 280@20 )

.value_( 0.5 )

.background_( Color.gray(0.5) )

.action_({ process.value }),

GUI.staticText.new( window, 100@20 )

.string_( item.asString )

.stringColor_( Color.gray(0.5) )

] });

button = GUI.button.new( window, 80@20 ).states_( [[ "new colors" ]] )

.action_({

({ |i| Color.rand(0.0,1.0); } ! 9)

.sort({ |a,b| a.hue <= b.hue })

.do({ |color, i| comps[i].background_( color ) });

process.value;

});

button.doAction;

GUI.button.new( window, 80@20 ).states_( [[ "reset sliders" ]] )

.action_({ sliders.do({ |sl| sl[1].value = 0.5; }); process.value });

)